package com.zzw.paymentdemo.controller;

import com.google.gson.Gson;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.zzw.paymentdemo.service.WxPayService;
import com.zzw.paymentdemo.util.HttpUtils;
import com.zzw.paymentdemo.util.WechatPay2ValidatorForRequest;
import com.zzw.paymentdemo.vo.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;


/**
 * @author zzw
 * @date 2023/5/11 16:32
 */
@Slf4j
@CrossOrigin //支持跨域
@RestController
@RequestMapping("/api/wx-pay")
@Api(tags = "微信支付API接口")
public class WxPayController {


    @Autowired
    WxPayService wxPayService;
    @Autowired
    Verifier verifier;

    @ApiOperation("调用统一下单API，生成支付二维码")
    @PostMapping("/native/{productId}")
    public R nativePay(@PathVariable Long productId) throws Exception {
        log.info("发起支付请求");
//        返回支付二维码链接和订单号
        Map<String,Object> map=wxPayService.nativePay(productId);

        return R.ok().setData(map);
    }

    /**
     * 支付通知
     * 微信支付通过支付通知接口将用户支付成功消息通知给商户
     */
    @ApiOperation("支付通知")
    @PostMapping("/native/notify")
    public String nativeNotify(HttpServletRequest request, HttpServletResponse response){
        Map<String, String> map = new HashMap<>();
        Gson gson = new Gson();
        try {
//        获取通知参数
            String body = HttpUtils.readData(request);
            Map<String,Object> bodyMap = gson.fromJson(body, Map.class);
            String requestId  = (String)bodyMap.get("id");
            log.info("通知id:{}",bodyMap.get("id"));
            log.info("通知参数:{}",bodyMap);


//            模拟失败应答
//            int i=1/0;

//            模拟超时应答
//            TimeUnit.SECONDS.sleep(5);

            // 验签
            WechatPay2ValidatorForRequest validator =
                    new WechatPay2ValidatorForRequest(verifier, body, requestId);
            if(!validator.validate(request)){
                log.info("通知验签失败");
                response.setStatus(500);
                map.put("code", "ERROR");
                map.put("message", "通知验签失败");
                return gson.toJson(map);
            }
            log.info("通知验签成功");

            // 回调通知后处理订单
            wxPayService.processOrder(bodyMap);
//            应答超时
//            设置响应超时，可以接收到微信支付的重复的支付结果通知。
//            通知重复，数据库会记录多余的支付日志
//            TimeUnit.SECONDS.sleep(5);


//        成功应答 必须为200或204
            log.info("成功应答");
            response.setStatus(200);
            map.put("code", "SUCCESS");
            map.put("message", "成功");
            return gson.toJson(map);
        }catch (Exception e){
//        失败应答 500，4xx
            log.info("失败应答");
            response.setStatus(500);
            map.put("code", "ERROR");
            map.put("message", "失败");
            return gson.toJson(map);
        }



    }


    @ApiOperation("申请退款")
    @PostMapping("/refunds/{orderNo}/{reason}")
    public R refunds(@PathVariable String orderNo,@PathVariable String reason) throws Exception {
        log.info("申请退款");
        wxPayService.refunds(orderNo, reason);
        return R.ok();
    }

    /**
     * 退款结果通知
     * 退款状态改变后，微信会把相关退款结果发送给商户。
     */
    @ApiOperation("退款通知")
    @PostMapping("/refunds/notify")
    public String refundsNotify(HttpServletRequest request, HttpServletResponse response){
        Map<String, String> map = new HashMap<>();
        Gson gson = new Gson();
        try {
//        获取通知参数
            String body = HttpUtils.readData(request);
            Map<String,Object> bodyMap = gson.fromJson(body, Map.class);
            String requestId  = (String)bodyMap.get("id");
            log.info("通知id:{}",bodyMap.get("id"));
            log.info("通知参数:{}",bodyMap);


//            模拟失败应答
//            int i=1/0;

//            模拟超时应答
//            TimeUnit.SECONDS.sleep(5);

            // 验签
            WechatPay2ValidatorForRequest validator =
                    new WechatPay2ValidatorForRequest(verifier, body, requestId);
            if(!validator.validate(request)){
                log.info("通知验签失败");
                response.setStatus(500);
                map.put("code", "ERROR");
                map.put("message", "通知验签失败");
                return gson.toJson(map);
            }
            log.info("通知验签成功");

            // 回调通知后处理退款单
            wxPayService.processRefund(bodyMap);
//            应答超时
//            设置响应超时，可以接收到微信支付的重复的支付结果通知。
//            通知重复，数据库会记录多余的支付日志
//            TimeUnit.SECONDS.sleep(5);


//        成功应答 必须为200或204
            log.info("成功应答");
            response.setStatus(200);
            map.put("code", "SUCCESS");
            map.put("message", "成功");
            return gson.toJson(map);
        }catch (Exception e){
//        失败应答 500，4xx
            log.info("失败应答");
            response.setStatus(500);
            map.put("code", "ERROR");
            map.put("message", "失败");
            return gson.toJson(map);
        }



    }
}
